#ifndef WINGCOROUTINE_P_H
#define WINGCOROUTINE_P_H

#include "WingCoroutine_global.h"

#include <list>
#include <semaphore>
#include <signal.h>
#include <thread>

#define NAKED __attribute__((naked))
#define UNUSED __attribute__((unused))

namespace Wing {
class WingCoroutine;
}

class WingCoroutine_p {
public:
  WingCoroutine_p(size_t stackSize);

  static void NAKED FASTCALL swapContext(const Wing::ThreadInfo &oldth,
                                         const Wing::ThreadInfo &newth,
                                         Wing::WingCoroutine *p);

  void swapContextCaller(Wing::WingCoroutine *p);

  bool sendCOAPC(const Wing::CO_APC &co_apc);

  size_t stackSize() const;

  Wing::ThreadID getID();

  void requeueID(Wing::ThreadID ID);

public:
  std::thread _hostThread;
  std::list<Wing::ThreadInfo> _threads;
  std::list<Wing::ThreadInfo>::iterator _currentThread;
  std::list<Wing::CO_APC> _apcs;
  sig_atomic_t _keepRunning = 1;

  std::binary_semaphore _sm;

private:
  size_t _stackSize;
  std::list<Wing::ThreadID> _ids;
  Wing::ThreadID _idLimit;
};

#endif // WINGCOROUTINE_P_H
